package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println(max(10, 5))

	fmt.Println(test(5, 6, "和为："))

	s1 := demo(fn)
	fmt.Println(s1)

	s2 := format(formatFun, "%d, %d", 10, 20)
	fmt.Println(s2)

	a, b := sum(30, 15)
	fmt.Println(a, b)

	c, d, e := demo2()
	fmt.Println(c, d, e)

	var f, g = 2, 3
	demo3(&f, &g)
	fmt.Println(f, g)

	k := []int{1, 2, 3, 4, 5, 6}
	res := demo4("sum: %d", k...)
	fmt.Println(res)

	//匿名函数
	sqrt := func(a float64) float64 {
		return math.Sqrt(a)
	}
	fmt.Println(sqrt(10))

	//在定义时调用匿名函数
	func(data int) {
		fmt.Println(data)
	}(10)

	visit([]int{4, 5, 6}, func(v int) {
		fmt.Println(v)
	})

	m, n := demo5(8, 6)
	fmt.Println(m())
	fmt.Println(n(3))

}

//基本写法
func max(n1, n2 int) int {
	if n1 > n2 {
		return n1
	}
	return n2
}

//返回多个值
func test(x, y int, s string) (int, string) {
	sum := x + y
	return sum, fmt.Sprintf(s, sum)
}

//函数作为参数
func demo(fn func(int2 int) int) int {
	return fn(30)
}

func fn(int2 int) int {
	return int2
}

// 定义函数类型
type FormatFunc func(s string, x, y int) string

func format(fn FormatFunc, s string, x, y int) string {
	return fn(s, x, y)
}

func formatFun(s string, x, y int) string {
	return fmt.Sprintf(s, x, y)
}

//多个返回值
func sum(a, b int) (int, int) {
	return a, b
}

//返回值命名
func demo2() (names []string, m map[string]int, num int) {
	m = make(map[string]int)
	m["a"] = 5

	return
}

//引用传递
func demo3(x, y *int) {
	*x, *y = *y, *x
}

//不定参数
func demo4(str string, n ...int) string {
	var x int
	for _, i := range n {
		x += i
	}
	return fmt.Sprintf(str, x)
}

//匿名函数用作回调函数
func visit(list []int, f func(int)) {
	for _, i := range list {
		f(i)
	}
}

//返回多个匿名函数
func demo5(x, y int) (func() int, func(int) int) {
	sum2 := func() int {
		return x + y
	}

	avg := func(z int) int {
		return (x + y) * z
	}
	return sum2, avg
}
